package com.cazz1.aiprr;

import java.io.IOException;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener {

	private SensorManager sensorManager;
	TextView text_X;
	TextView text_Y;
	TextView text_Z;
	TextView text_Yaw;
	TextView text_Pitch;
	TextView text_Roll;
	TextView text_accelerationSquareRoot;
	TextView text_accelerationSquareRootInt;
	private long lastUpdate;
	MediaPlayer mPlayer;
	float accelerationSquareRoot;
	
	private boolean alphaStatic = false;

	// Constants for the low-pass filters
	private float timeConstant = 0.18f;
	private float alpha = 0.9f;
	private float dt = 0;

	// Timestamps for the low-pass filters
	private float timestamp = System.nanoTime();
	private float timestampOld = System.nanoTime();

	private int count = 0;

	// Gravity and linear accelerations components for the
	// Wikipedia low-pass filter
	private float[] gravity = new float[]
	{ 0, 0, 0 };

	private float[] linearAcceleration = new float[]
	{ 0, 0, 0 };

	// Raw accelerometer data
	private float[] input = new float[]
	{ 0, 0, 0 };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
				SensorManager.SENSOR_DELAY_NORMAL);

		// Collegamento con le textView del layout
		text_X = (TextView) findViewById(R.id.textViewX);
		text_Y = (TextView) findViewById(R.id.textViewY);
		text_Z = (TextView) findViewById(R.id.textViewZ);

		text_Yaw = (TextView) findViewById(R.id.textViewYaw);
		text_Pitch = (TextView) findViewById(R.id.textViewPitch);
		text_Roll = (TextView) findViewById(R.id.textViewRoll);

		text_accelerationSquareRoot = (TextView) findViewById(R.id.textViewAcceleration);
		text_accelerationSquareRootInt = (TextView) findViewById(R.id.textViewAccelerationInt);
		
		lastUpdate = System.currentTimeMillis();
		
		if(mPlayer==null){
			mPlayer = MediaPlayer.create(this, R.raw.prr);
		}
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		Sensor sensor = event.sensor;
		float[] values = event.values;
		synchronized (this) {
			Log.d("Aiprr", "onSensorChanged: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: "
					+ values[2]);
			if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
				float X = values[0];
				float Y = values[1];
				float Z = values[2];
				accelerationSquareRoot = (X * X + Y * Y + Z * Z)
						/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
			
				text_Yaw.setText("X: " + (int)X);
				text_Pitch.setText("Y: " + (int)Y);
				text_Roll.setText("Z: " + (int)Z);
				
				text_accelerationSquareRoot.setText("Acc:" + accelerationSquareRoot);
				text_accelerationSquareRootInt.setText("Acc:" + (int)accelerationSquareRoot);
				
				removeGravity(event);
			}
			
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub
	}

	@Override
	protected void onPause() {
		// unregister listener
		super.onPause();
		sensorManager.unregisterListener(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		// register this class as a listener for the orientation and
		// accelerometer sensors
		sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
				SensorManager.SENSOR_DELAY_NORMAL);
	}
	
	private void removeGravity(SensorEvent event){
		// alpha is calculated as t / (t + dT)
        // with t, the low-pass filter's time-constant
        // and dT, the event delivery rate

		float[] values = event.values;
		
		if (!alphaStatic)
		{
			timestamp = System.nanoTime();
			// Find the sample period (between updates).
			// Convert from nanoseconds to seconds
			dt = 1 / (count / ((timestamp - timestampOld) / 1000000000.0f));
			alpha = timeConstant / (timeConstant + dt);

		}

		count++;
		if (count > 5)
		{
			gravity[0] = alpha * gravity[0] + (1 - alpha) * values[0];
			gravity[1] = alpha * gravity[1] + (1 - alpha) * values[1];
			gravity[2] = alpha * gravity[2] + (1 - alpha) * values[2];

			linearAcceleration[0] = values[0] - gravity[0];
			linearAcceleration[1] = values[1] - gravity[1];
			linearAcceleration[2] = values[2] - gravity[2];
		}
		
		text_X.setText("X: " + linearAcceleration[0]);
		text_Y.setText("Y: " + linearAcceleration[1]);
		text_Z.setText("Z: " + linearAcceleration[2]);
		
		int X_int = (int)linearAcceleration[0];
		int Y_int = (int)linearAcceleration[1];
		int Z_int = (int)linearAcceleration[2];
		
		text_Yaw.setText("X: " + X_int);
		text_Pitch.setText("Y: " + Y_int);
		text_Roll.setText("Z: " + Z_int);
		
		long actualTime = System.currentTimeMillis();
	    if (linearAcceleration[2]>2.3 && accelerationSquareRoot >= 2.3) //
	    {
	      if (actualTime - lastUpdate < 400) {
	        return;
	      }
	      lastUpdate = actualTime;
	      mPlayer.start();
		} else {
			if(mPlayer.isPlaying()){
				mPlayer.pause();
			}
		}
	}

	/**
	 * Indicate if alpha should be static.
	 * @param alphaStatic A static value for alpha
	 */
	public void setAlphaStatic(boolean alphaStatic)
	{
		this.alphaStatic = alphaStatic;
	}

	/**
	 * Set static alpha.
	 * @param alpha The value for alpha, 0 < alpha <= 1
	 */
	public void setAlpha(float alpha)
	{
		this.alpha = alpha;
	}
	
}